package com.example.rouroudate.ui.gallery.ui

import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.core.content.ContextCompat
import com.example.rouroudate.R
import com.example.rouroudate.util.DisplayUtils
import java.lang.Integer.min
import java.lang.Math.PI
import kotlin.math.cos
import kotlin.math.sin

class StyleAnimationView @JvmOverloads
constructor(
    context: Context,
    type: Int = CircleType,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    companion object {
        const val TAG = "StyleAnimationView"
        const val CircleType = 1

        const val HeartType = 2

        const val FiveASType = 3

        val typeArray = mutableListOf(CircleType, HeartType, FiveASType)
    }

    private val centerPoint = PointF()

    private val shapePath = Path()

    private val dstPath = Path()

    private val pathMeasure = PathMeasure()

    private var animationValue = 0f

    private var len = 0f

    private var status = 0

    private val h = (DisplayUtils.getScreenHeight() * 0.3).toInt()

    private val w = DisplayUtils.getScreenWidth()

    private val rect = RectF()

    private var animator = ValueAnimator.ofFloat(0f, 1f).apply {
        duration = 1000
        repeatCount = 2
        repeatMode = ValueAnimator.REVERSE
        interpolator = AccelerateDecelerateInterpolator()
        addUpdateListener {
            animationValue = it.animatedValue as Float
            invalidate()
        }
        addListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(p0: Animator?) {
                status = 0
            }

            override fun onAnimationEnd(p0: Animator?) {
                status += 1
            }

            override fun onAnimationCancel(p0: Animator?) {
            }

            override fun onAnimationRepeat(p0: Animator?) {
                status += 1
                animationValue = 0f
            }
        })
    }

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        strokeWidth = DisplayUtils.dp2px(4f).toFloat()
        style = Paint.Style.STROKE
        color = ContextCompat.getColor(context, R.color.pink)
        strokeCap = Paint.Cap.ROUND
        strokeJoin = Paint.Join.ROUND
    }

    init {
        setBackgroundColor(ContextCompat.getColor(context, R.color.light_hurt_color_2))
        centerPoint.set((w / 2).toFloat(), (h / 2).toFloat())
        val radius = min(w, h) * 0.5f / 2f
        rect.set(
            centerPoint.x - radius,
            centerPoint.y - radius,
            centerPoint.x + radius,
            centerPoint.y + radius
        )
        when (type) {
            CircleType -> {
                shapePath.addArc(rect, 270f, 360f)
            }
            HeartType -> {
                shapePath.moveTo(rect.left + radius, (rect.top + rect.bottom) * 0.34f)
                shapePath.cubicTo(
                    rect.right - radius * 0.3f, rect.top - radius * 0.7f,
                    rect.right + radius * 0.8f, rect.top + radius * 0.9f,
                    rect.left + radius, rect.bottom
                )
                shapePath.cubicTo(
                    rect.left - radius * 0.8f, rect.top + radius * 0.9f,
                    rect.left + radius * 0.3f, rect.top - radius * 0.7f,
                    rect.left + radius, (rect.top + rect.bottom) * 0.34f
                )
                shapePath.close()
            }
            else -> {
                val circlePath = Path()
                val fivePathMeasure = PathMeasure()
                val angle = 5
                val pos = FloatArray(2)
                var startAngle = 270f
                val sweepAngle = 360f / angle
                repeat(angle) {
                    circlePath.reset()
                    circlePath.addArc(rect, startAngle, sweepAngle)
                    fivePathMeasure.setPath(circlePath, false)
                    fivePathMeasure.getPosTan(0f, pos, null)
                    when (it) {
                        0 -> shapePath.moveTo(pos[0], pos[1])
                        else -> shapePath.lineTo(pos[0], pos[1])
                    }
                    startAngle += sweepAngle
                }
                shapePath.close()
            }
        }
        pathMeasure.setPath(shapePath, true)
        len = pathMeasure.length
    }

    fun startAnimation() {
        status = 0
        animator.start()
    }

    fun cancelAnimation() {
        animator.cancel()
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?.let {
            when (status) {
                0, 1 -> {
                    dstPath.reset()
                    val end = animationValue * len
                    val start =
                        (end - ((0.5 - kotlin.math.abs(animationValue - 0.5f)) * len)).toFloat()
                    pathMeasure.getSegment(start, end, dstPath, true)

                    it.save()
                    it.drawPath(dstPath, paint)
                    it.restore()
                }
                2 -> {
                    dstPath.reset()
                    val end = animationValue * len
                    pathMeasure.getSegment(0f, end, dstPath, true)
                    it.save()
                    it.drawPath(dstPath, paint)
                    it.restore()
                }
                else -> {
                    it.save()
                    it.drawPath(shapePath, paint)
                    it.restore()
                }
            }

        }
    }
}